package
{
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.StageDisplayState;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;

	public class Game
	{
		protected var backBuffer:BitmapData;
		protected static var stateStack:StateStack;
		protected static var myGraphics:MyGraphics;
		protected static var mainWindow:Sprite;
		protected var tBegin:int = 0;
		protected static var instance:Game;
		public function Game(width:int, height:int, main:Sprite)
		{
			instance = this;
			stateStack = new StateStack();
			myGraphics = new MyGraphics(width, height);
			mainWindow = main;
			
			mainWindow.addEventListener(Event.ENTER_FRAME,Render);
			mainWindow.stage.addEventListener(MouseEvent.MOUSE_MOVE,MouseMove);
			mainWindow.stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDown);
			mainWindow.stage.addEventListener(MouseEvent.MOUSE_UP,MouseUp);
			mainWindow.stage.addEventListener(MouseEvent.CLICK,MouseClick);
			mainWindow.stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDown);
		}
		public static function GetStateStack():StateStack
		{
			return stateStack;
		}
		public static function GetWidth():int
		{
			return myGraphics.Width();
		}
		public static function GetHeight():int
		{
			return myGraphics.Height();
		}
		public static function GetMyGraphics():MyGraphics
		{
			return myGraphics;
		}
		public static function GetMainWindow():Sprite
		{
			return mainWindow;
		}
		public static function GetInstance():Game
		{
			return instance;
		}
		protected function KeyDown(event:KeyboardEvent):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
			{
				Game.GetStateStack().GetCurrent().KeyDown(event.keyCode);
			}
		}
		protected function Render(event:Event):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
			{
				var tNew:int = flash.utils.getTimer();
				Game.GetStateStack().GetCurrent().Update(tNew - tBegin);
				tBegin = tNew;
				Game.GetStateStack().GetCurrent().Render(Game.GetMyGraphics());
			}
			Game.GetMyGraphics().Flip(mainWindow.graphics);
		}
		protected function MouseMove(eventObject:MouseEvent):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
				Game.GetStateStack().GetCurrent().MouseMove(eventObject.localX,eventObject.localY, eventObject.buttonDown);
		}
		protected function MouseDown(eventObject:MouseEvent):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
				Game.GetStateStack().GetCurrent().MouseDown(eventObject.localX,eventObject.localY);
		}
		protected function MouseUp(eventObject:MouseEvent):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
				Game.GetStateStack().GetCurrent().MouseUp(eventObject.localX,eventObject.localY);
		}
		protected function MouseClick(eventObject:MouseEvent):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
				Game.GetStateStack().GetCurrent().MouseClick(eventObject.localX,eventObject.localY);
		}
		public function ReceiveMessage(mess:String,param:Array,sender:MovieClip):void
		{
			if(Game.GetStateStack().GetCurrent() != null)
				Game.GetStateStack().GetCurrent().ReceiveMessage(mess,param,sender);
		}
		public static function SwitchToFullScreen(scale:Boolean):void
		{
			if(scale)
			{
				GetMainWindow().stage.scaleMode = StageScaleMode.SHOW_ALL;
			}
			else
			{
				GetMainWindow().stage.scaleMode = StageScaleMode.NO_SCALE;
			}
			GetMainWindow().stage.displayState = StageDisplayState.FULL_SCREEN;
		}
		
	}
}